package cn.aezo.minions.gen.handler;

import cn.aezo.minions.common.Result;
import cn.aezo.minions.gen.Context;
import cn.aezo.minions.gen.model.ProjectConfig;
import cn.aezo.minions.gen.model.TemplateItem;
import cn.aezo.minions.gen.render.Render;
import cn.aezo.utils.base.ValidU;
import freemarker.template.TemplateException;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author smalle
 * @date 2019-07-31 11:20
 */
public abstract class GenCodeHandler {
    protected ProjectConfig projectConfig;
    protected Context context;
    protected Render render;

    /**
     * 初始化上下文
     * @param context
     * @return
     */
    public abstract Result initContext(Context context);

    /**
     * 执行代码生成
     * @param contextParam
     * @return
     */
    public abstract Result handleGenCode(Context contextParam);

    public Result init(Context context) {

        Result ctxRes = initContext(context);
        if(Result.isError(ctxRes)) return ctxRes;

        context.getExt().put(this.getClass().getName(), this);
        return Result.success();
    }

    protected void doGen() throws IOException, TemplateException {
        // 渲染逻辑参数
        Map<String, Object> dataContext = new HashMap<>();
        dataContext.put("renderDir", context.getModuleRootDir());
        dataContext.put("templateItems", context.getTemplate().getTemplateItems());

        // 渲染所有模板文件
        render.render(context, dataContext);
    }

    protected Result checkTemplateType(Context contextParam, String templateTypeParam) {
        if(ValidU.isEmpty(templateTypeParam))
            return Result.failure("无效的模板类型");
        String templateType = contextParam.getTemplate().getTemplateType();
        List<TemplateItem> templateItems = contextParam.getTemplate().getTemplateItems();
        if(!templateTypeParam.equals(templateType) || ValidU.isEmpty(templateItems)) {
            return Result.failure("不支持此模板类型：" + templateTypeParam);
        }

        // 初始化对象
        context = contextParam;
        projectConfig = contextParam.getProjectConfig();
        return Result.success();
    }

    protected String getProjectModuleDirAbs() {
        if(context.getCurrentModule() == null) context.setCurrentModule("");
        if(!"".equals(context.getCurrentModule())) context.setCurrentModule("/" + context.getCurrentModule());
        return context.getRootDir() + context.getProjectDir() + context.getCurrentModule();
    }
}
